package com.lz.virtualthread.common.utils;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.servlet.http.HttpServletRequest;
import java.io.*;
import java.math.BigDecimal;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

public class FileUtil {
    private static final Logger logger = LoggerFactory.getLogger(FileUtil.class);

    /**
     * 获取IP地址
     *
     * @param request
     * @return
     */
    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip != null && !"".equals(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (ip != null && !"".equals(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }

    public static long getLineNumber(File file) {
        if (file.exists()) {
            try {
                FileReader fileReader = new FileReader(file);
                LineNumberReader lineNumberReader = new LineNumberReader(fileReader);
                lineNumberReader.skip(Long.MAX_VALUE);
                long lines = lineNumberReader.getLineNumber() + 1;
                fileReader.close();
                lineNumberReader.close();
                return lines;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return 0;
    }

    /**
     * 通过IP地址获取MAC地址
     *
     * @param ip String,127.0.0.1格式
     * @return mac String
     * @throws Exception
     */
    public static String getMACAddress(String ip) throws Exception {
//        String line = "";
//        String MAC_ADDRESS_PREFIX = "MAC Address = ";
//        String MAC_ADDRESS_PREFIX2 = "MAC 地址 = ";
//        String LOOPBACK_ADDRESS = "127.0.0.1";
//        String LOOPBACK_ADDRESS2 = "localhost";
//        //如果为127.0.0.1,则获取本地MAC地址。
//        if (LOOPBACK_ADDRESS.equals(ip) || LOOPBACK_ADDRESS2.equals(ip)) {
//            InetAddress inetAddress = InetAddress.getLocalHost();
//            //貌似此方法需要JDK1.6。
//            byte[] mac = NetworkInterface.getByInetAddress(inetAddress).getHardwareAddress();
//            //下面代码是把mac地址拼装成String
//            StringBuilder sb = new StringBuilder();
//            for (int i = 0; i < mac.length; i++) {
//                if (i != 0) {
//                    sb.append("-");
//                }
//                //mac[i] & 0xFF 是为了把byte转化为正整数
//                String s = Integer.toHexString(mac[i] & 0xFF);
//                sb.append(s.length() == 1 ? 0 + s : s);
//            }
//            //把字符串所有小写字母改为大写成为正规的mac地址并返回
//            return sb.toString().trim().toUpperCase();
//        }
//        //获取非本地IP的MAC地址
//        Process p = Runtime.getRuntime().exec("nbtstat -A " + ip);
//        InputStreamReader isr = new InputStreamReader(p.getInputStream(), "GB2312");
//        BufferedReader br = new BufferedReader(isr);
//        try {
//
//            while ((line = br.readLine()) != null) {
//                if (line.trim() != null) {
//                    int index = line.indexOf(MAC_ADDRESS_PREFIX);
//                    int index2 = line.indexOf(MAC_ADDRESS_PREFIX2);
//                    if (index != -1) {
//                        return line.substring(index + MAC_ADDRESS_PREFIX.length()).trim().toUpperCase();
//                    }else if(index2 != -1){
//                    	return line.substring(index + MAC_ADDRESS_PREFIX2.length()).trim().toUpperCase();
//                    }
//                }
//            }
//        } catch (IOException e) {
//            e.printStackTrace(System.out);
//        }
//        finally{
//            br.close();
//        }
        return "";
    }

    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }


    public static String getMacAddress(String ip) {
        logger.info(ip);
        if ("127.0.0.1".equals(ip)) {

        }
        String macAddress = "";
        BufferedReader inputs = null;
        try {
            String scancmd = "nbtstat -A ";
            File file = new File("C:\\Windows\\SysWOW64");
            if (file.exists()) {
                scancmd = "C:\\Windows\\System32\\nbtstat.exe -A ";
            }
            String command = scancmd + ip;
            if ("127.0.0.1".equals(ip)) {
                command = "ipconfig -all ";
            }
            Process p = Runtime.getRuntime().exec(command);
            InputStreamReader ir = new InputStreamReader(
                    p.getInputStream(), "gbk");
            inputs = new BufferedReader(ir);
            String line;
            while ((line = inputs.readLine()) != null) {
                if (line.indexOf("MAC Address") > 0) {
                    macAddress = line.substring(
                            line.indexOf("MAC Address") + 14, line.length());
                }
                if (line.indexOf("MAC 地址") > 0) {
                    macAddress = line.substring(
                            line.indexOf("MAC Address") + 14, line.length());
                }
                if ("127.0.0.1".equals(ip) && line.indexOf("物理地址") > 0) {
                    logger.info(line);
                    macAddress = line.substring(
                            line.indexOf("物理地址") + 31, line.length());
                }
            }
            logger.info(macAddress);
        } catch (IOException e) {
            e.printStackTrace(System.out);
        }
        return macAddress;
    }


    /**
     * 获取文件的创建时间：windows下可获取，linux下只能获取file.lastModified()
     *
     * @param filePath
     * @return
     */
    public static Long getFileCreateTime(String filePath) {
        File file = new File(filePath);
        try {
            Path path = Paths.get(filePath);
            BasicFileAttributeView basicview = Files.getFileAttributeView(path, BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
            BasicFileAttributes attr = basicview.readAttributes();
            return attr.creationTime().toMillis();
        } catch (Exception e) {
            e.printStackTrace();
            return file.lastModified();
        }
    }

    /*
     * 获取目录下所有的文件绝对路径
     *
     * @param homePath
     * @return
     */
    public static List<String> listFiles(String homePath) {
        List<String> savePathAndFile = new ArrayList<>();
        LinkedList<String> stack = new LinkedList<>();
        File homeDir = new File(homePath);
        if (homeDir.exists()) {
            stack.add(homePath);
        }
        while (!stack.isEmpty()) {
            String path = stack.pollLast();
            File file = new File(path);
            if (file.isDirectory()) {
                for (File f : file.listFiles()) {
                    stack.add(f.getAbsolutePath());
                }
            } else {
                savePathAndFile.add(file.getAbsolutePath());
            }
        }
        return savePathAndFile;
    }

    /**
     * 获取目录下所有的文件路径和对应文件的层数,控制查找的层数,非递归
     *
     * @param homePath
     * @return
     */
    public static List<String> listFiles(String homePath, int controlDeep) {
        List<String> savePathAndFile = new ArrayList<>();
        LinkedList<String> stack = new LinkedList<>();
        File homeDir = new File(homePath);
        if (homeDir.exists()) {
            stack.add(homePath);
        }
        int deep = 1;
        while (!stack.isEmpty() && deep <= controlDeep) {
            String path = stack.pollLast();
            File file = new File(path);
            if (file.isDirectory()) {
                for (File f : file.listFiles()) {
                    stack.add(f.getAbsolutePath());
                }
                ++deep;
            } else {
                savePathAndFile.add(file.getAbsolutePath());
            }
        }

        return savePathAndFile;
    }

    /**
     * 文件路径集合转logFile集合
     *
     * @param calcLogPaths
     * @return
     */
    public static List<LogFile> filePathsToLogFiles(List<String> calcLogPaths) {
        List<LogFile> calcLogFiles = calcLogPaths.stream().map(logFilePath -> {
            LogFile logFile = new LogFile();
            File fileTemp = new File(logFilePath);
            logFile.setFileAbsolutePath(fileTemp.getAbsolutePath());
            logFile.setFileRelativePath(fileTemp.getPath());
            LocalDateTime createFileTime = DateLogUtil.millisToDate(FileUtil.getFileCreateTime(logFilePath));
            logFile.setCreateDateTime(createFileTime);
            logFile.setCreateDateTimeStr(DateLogUtil.formatTime(createFileTime));
            LocalDateTime lastModifyFileTime = DateLogUtil.millisToDate(fileTemp.lastModified());
            logFile.setLastModifyDateTime(lastModifyFileTime);
            logFile.setLastModifyDateTimeStr(DateLogUtil.formatTime(lastModifyFileTime));
            logFile.setFileName(fileTemp.getName());
            DecimalFormat format = new DecimalFormat("#,##0.##");
            BigDecimal decimal = BigDecimal.valueOf(Double.valueOf(fileTemp.length()) / 1024 / 1024);
            logFile.setFileSize(format.format(decimal));
            return logFile;
        }).collect(Collectors.toList());
        return calcLogFiles;
    }

    public static String readFileContent(String fileName) {
        File file = new File(fileName);
        BufferedReader reader = null;
        StringBuffer sbf = new StringBuffer();
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempStr;
            while ((tempStr = reader.readLine()) != null) {
                sbf.append(tempStr);
            }
            reader.close();
            return sbf.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return sbf.toString();
    }

    public static void deleteDirectoryStream(Path path) {
        try {

            Files.walkFileTree(path,
                    new SimpleFileVisitor<Path>() {
                        // 先去遍历删除文件
                        @Override
                        public FileVisitResult visitFile(Path file,
                                                         BasicFileAttributes attrs) throws IOException {
                            if (Files.isDirectory(file)) {
                                deleteDirectoryStream(file);
                            } else {
                                Files.delete(file);
                            }

                            return FileVisitResult.CONTINUE;
                        }

                        // 再去遍历删除目录
                        @Override
                        public FileVisitResult postVisitDirectory(Path dir,
                                                                  IOException exc) throws IOException {
                            Files.delete(dir);

                            return FileVisitResult.CONTINUE;
                        }

                    }
            );

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        List<String> fileEncode = listFiles("D:\\workxQant\\jtProject\\xIR_J2EE\\src\\main\\log");
        //String fileEncode2 = getFileEncode("D:\\GJ_CALC\\Common\\Log\\xetlLog.txt.8");
        logger.info("fileEncode = " + fileEncode);
        //logger.info("fileEncode2 = " + fileEncode2);
    }


}